/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package NodeManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Date;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;

/**
 *
 * @author Sean
 */
public class ManagedFile {

    public RdfModelManager FileManager;
    public String FileName = null;
    public Node FirstNode = null;
    public Node SecondNode = null;

    protected boolean VerifyNodes() {
        File file;
        Node node1 = null;
        Node node2 = null;

        file = FileManager.GetPhysicalFile(FileName);

        try {

            // ensure that the managed file is a member of at least 2 nodes.
            if (SecondNode == null) {
                if (FirstNode.NodeName.equalsIgnoreCase(FileManager.GetNode1().NodeName)) {
                    node1 = FileManager.GetNode2();
                    node2 = FileManager.GetNode3();
                }
                if (FirstNode.NodeName.equalsIgnoreCase(FileManager.GetNode2().NodeName)) {
                    node1 = FileManager.GetNode1();
                    node2 = FileManager.GetNode3();
                }
                if (FirstNode.NodeName.equalsIgnoreCase(FileManager.GetNode3().NodeName)) {
                    node1 = FileManager.GetNode1();
                    node2 = FileManager.GetNode2();
                }
                FileManager.AddFileToOneOfTwoNodes(file, node1, node2, false);
                return true;
            }
            
        } catch (Exception e) {
        }

        return false;
    }

    protected boolean isDamaged() {
        boolean damagedNode = false;

        File f1 = new File(FirstNode.GetLocation() + File.separatorChar + FileName);
        if (!f1.exists()) {
            damagedNode = true;
        }

        File f2 = new File(SecondNode.GetLocation() + File.separatorChar + FileName);
        if (!f2.exists()) {
            damagedNode = true;
        }

        return damagedNode;
    }

    protected void repairDamage() {

        File f1 = new File(FirstNode.GetLocation() + File.separatorChar + FileName);
        File f2 = new File(SecondNode.GetLocation() + File.separatorChar + FileName);

        try {
            if (!f1.exists() &&
                    !f2.exists()) {
                this.FileManager.DeleteFile(FileName);
            } else if (!f1.exists()) {
                this.FileManager.DeleteFile(FileName, FirstNode.NodeName);
                this.FileManager.AddFileToOneNode(f2, FirstNode, true);
            } else if (!f2.exists()) {
                this.FileManager.DeleteFile(FileName, SecondNode.NodeName);
                this.FileManager.AddFileToOneNode(f1, SecondNode, true);
            }

        } catch (IOException ie) {
            System.out.println("Exception when adding a file to one node:" + ie.toString());
        }

    }

    protected void updateFileToCurrent() {
        File f1 = new File(FirstNode.GetLocation() + File.separatorChar + FileName);
        File f2 = new File(SecondNode.GetLocation() + File.separatorChar + FileName);

        if (f1.lastModified() > f2.lastModified() && this.isUpdated()) {
            try {
                this.FileManager.DeleteFile(FileName, SecondNode.NodeName);
                this.FileManager.AddFileToOneNode(f1, SecondNode, true);
            } catch (IOException ie) {
                System.out.println("Exception when adding a file to one node:" + ie.toString());
            }

        } else if (f1.lastModified() < f2.lastModified() && this.isUpdated()) {
            try {
                this.FileManager.DeleteFile(FileName, FirstNode.NodeName);
                this.FileManager.AddFileToOneNode(f2, FirstNode, true);
            } catch (IOException ie) {
                System.out.println("Exception when adding a file to one node:" + ie.toString());
            }

        }

    }

    protected boolean isUpdated() {
        boolean isequal = true;

        String f1 = FirstNode.GetLocation() + File.separatorChar + FileName;
        String f2 = SecondNode.GetLocation() + File.separatorChar + FileName;

        try {

            CheckedInputStream cis = null;
            CheckedInputStream cis2 = null;
            long fileSize = 0;
            long file2Size = 0;
            Date dt1 = new Date();
            Date dt2 = new Date();

            try {
                // Computer CRC32 checksum
                cis = new CheckedInputStream(
                        new FileInputStream(f1), new CRC32());

                cis2 = new CheckedInputStream(
                        new FileInputStream(f2), new CRC32());

                fileSize = new File(f1).length();
                file2Size = new File(f2).length();

                dt1.setTime(new File(f1).lastModified());
                dt2.setTime(new File(f2).lastModified());

            } catch (FileNotFoundException e) {
                System.err.println("File not found.");
                System.exit(1);
            }

            byte[] buf = new byte[128];
            while (cis.read(buf) >= 0) {
            }

            while (cis2.read(buf) >= 0) {
            }

            long checksum = cis.getChecksum().getValue();
            System.out.println(checksum + " " + fileSize + " " + f1 + " " + dt1.toString());

            long checksum2 = cis2.getChecksum().getValue();
            System.out.println(checksum2 + " " + file2Size + " " + f2 + " " + dt2.toString());

            isequal = (checksum == checksum2);

            cis.close();
            cis2.close();
            
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }

        return !isequal;
    }
}
